using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesGDB;
using arcgis_example.ChildForm;
using ESRI.ArcGIS.Controls;

namespace arcgis_example
{
    public partial class ExampleMain : Form
    {
        public ExampleMain()
        {
            InitializeComponent();
        }

        private void 打开sdeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IWorkspace pWkspace = null;
            IPropertySet pPropertySet = new PropertySetClass();
            pPropertySet.SetProperty("SERVER", "140.143.228.133");
            pPropertySet.SetProperty("INSTANCE", "sde:sqlserver:140.143.228.133");
            pPropertySet.SetProperty("DATABASE", "TestDB");
            pPropertySet.SetProperty("USER", "SA");
            pPropertySet.SetProperty("PASSWORD", "a333666b.");
            pPropertySet.SetProperty("VERSION", "SDE.DEFAULT");
            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory");
            IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
            try
            {
                pWkspace = workspaceFactory.Open(pPropertySet, 0);

                IFeatureWorkspace FeatureWorkspace;
                FeatureWorkspace = pWkspace as IFeatureWorkspace;//传递给Feature 工作空间
                ESRI.ArcGIS.Geodatabase.IFeatureClass FeatureClass;
                FeatureClass = FeatureWorkspace.OpenFeatureClass("TestDB.dbo.PRO_SHP");//填充所需Feature 集合
                ESRI.ArcGIS.Carto.FeatureLayer FLayer = new ESRI.ArcGIS.Carto.FeatureLayerClass();
                FLayer.FeatureClass = FeatureClass;//将Feature 加载到图层
                FLayer.Name = "pro_shp_sql";
                axMapControl1.Map.ClearLayers();
                axMapControl1.Map.AddLayer(FLayer);//加载图层
                axMapControl1.Update();//更新空白区域
                axMapControl1.Refresh();//刷新地图视窗
            }
            catch (Exception EX)
            {
                MessageBox.Show(EX.ToString());
            }
            pPropertySet.SetProperty("SERVER", "140.143.228.133");
           
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void 打开矢量数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
           

            try
            {

                OpenFileDialog openFile = new OpenFileDialog();
                openFile.Filter = "shape文件(*.shp)|*.shp";
                openFile.Title = "打开文件";

                if (openFile.ShowDialog() == DialogResult.OK)
                {

                    String fullFilePath = openFile.FileName;

                    //获得文件路径

                    int index = fullFilePath.LastIndexOf("\\");
                    string filePath = fullFilePath.Substring(0, index);
                    //获得文件名称
                    string fileNam = fullFilePath.Substring(index + 1);
                    //加载shape文件
                    if (openFile.FilterIndex == 1)
                    {
                        //打开工作空间工厂
                        IWorkspaceFactory workspcFac = new ShapefileWorkspaceFactory();
                        IFeatureWorkspace featureWorkspc;
                        IFeatureLayer featureLay = new FeatureLayerClass();
                        //打开路径
                        featureWorkspc = workspcFac.OpenFromFile(filePath, 0) as IFeatureWorkspace;
                        //打开类要素
                        featureLay.FeatureClass = featureWorkspc.OpenFeatureClass(fileNam);
                        featureLay.Name = fileNam;
                        //清空图层
                        //axMapControl1.ClearLayers();
                        //添加图层
                        axMapControl1.AddLayer(featureLay);
                        axMapControl1.Refresh();

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }


        }

        private void 打开影像数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {

                OpenFileDialog openFile = new OpenFileDialog();
                openFile.Filter = "栅格数据(*.jpg,*.bmp,*.tiff)|*.jpg;*.bmp;*.tiff";
                openFile.Title = "打开文件";

                if (openFile.ShowDialog() == DialogResult.OK)
                {

                    String fullFilePath = openFile.FileName;

                    //获得文件路径

                    int index = fullFilePath.LastIndexOf("\\");
                    string filePath = fullFilePath.Substring(0, index);
                    //获得文件名称
                    string fileNam = fullFilePath.Substring(index + 1);
                    //加载文件
                   
                    IWorkspaceFactory workspcFac = new RasterWorkspaceFactory();
                    IRasterWorkspace rasterWorkspc;
                    IRasterDataset rasterDatst = new RasterDatasetClass();
                    IRasterLayer rasterLay = new RasterLayerClass();
                    rasterWorkspc = workspcFac.OpenFromFile(filePath, 0) as IRasterWorkspace;
                    rasterDatst = rasterWorkspc.OpenRasterDataset(fileNam);
                    rasterLay.CreateFromDataset(rasterDatst);
                    rasterLay.Name = fileNam;
                    axMapControl1.ClearLayers();
                    axMapControl1.AddLayer(rasterLay);
                    axMapControl1.Refresh();

                    axMapControl1.Refresh();

                    
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void 打开mxd工作空间ToolStripMenuItem_Click(object sender, EventArgs e)
        {


            try
            {

                OpenFileDialog openFile = new OpenFileDialog();
                openFile.Filter = "地图文档(*.mxd,*.mxt,*.jmf)|*.mxd;*.mxt;*.jmf";
                openFile.Title = "打开文件";

                if (openFile.ShowDialog() == DialogResult.OK)
                {
                    String fullFilePath = openFile.FileName;
                    axMapControl1.LoadMxFile(fullFilePath);


                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            } 
        }

        private void 打开gdb里的数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {

                FolderBrowserDialog openFile = new FolderBrowserDialog();
                openFile.Description = "GDB数据(*.gdb)|*.gdb";
               

                if (openFile.ShowDialog() == DialogResult.OK)
                {

                    String fullFilePath = openFile.SelectedPath;

                    IWorkspaceFactory pFactory = new FileGDBWorkspaceFactory(); 
                    //打开工作空间

                    IWorkspace pWorkspace = pFactory.OpenFromFile(fullFilePath, 0);
                    //打开要素集
           
                    IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;

                    IFeatureClass pFC = pFeatureWorkspace.OpenFeatureClass("pro_shp");                   
                    IFeatureLayer pFLayer = new FeatureLayerClass();
                    pFLayer.FeatureClass = pFC;
                    pFLayer.Name = pFC.AliasName;
                    ILayer pLayer = pFLayer as ILayer;
                    IMap pMap = axMapControl1.Map;
                    pMap.AddLayer(pLayer);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            } 

        }

        private void axMapControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
        {
           // button specifies which mouse button was pressed. 1 for the left mouse button, 2 for the right mouse button, and 4 for the middle mouse button.

            //shift specifies an integer corresponding to the state of the SHIFT (bit 0), CTRL (bit 1) and ALT (bit 2) keys. When none, some or all of these keys are pressed none, some or all the bits get set. These bits correspond to the values 1, 2, and 4, respectively. For example, if both SHIFT and ALT were pressed, ShiftState would return 5.
            if (e.button == 1)
            {
                IPoint point = axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
                ILayer pLayer = axMapControl1.get_Layer(0);
                List<IFeature> pFeaturesList = getPointSelect(point, pLayer as IFeatureLayer, 0.1);
                if (pFeaturesList.Count>0){
                   
                    IFeature feature = pFeaturesList[0];
                    InfoForm infoForm = new InfoForm();
                    //infoForm.Location = new System.Drawing.Point(e.x + infoForm.Width / 2+axMapControl1.Left, e.y + infoForm.Height / 2+axMapControl1.Top);
                    infoForm.SetDesktopLocation(e.x + axMapControl1.Left, e.y + axMapControl1.Top);
                    infoForm.Refresh();
                    infoForm.ShowDialog();
                }               


            }
        }

        private List<IFeature> getPointSelect(IPoint pPoint, IFeatureLayer pFeatureLayer, double pRadius)
        {
            List<IFeature> pSelectedFeatureList = new List<IFeature>();  //返回要素类

            ITopologicalOperator pTop = pPoint as ITopologicalOperator;
            IGeometry pGeometry = pTop.Buffer(pRadius);  //建立缓冲区
            ISpatialFilter pSpatialFilter = new SpatialFilterClass();  //空间查询模块
            pSpatialFilter.Geometry = pGeometry;  //查询内容
            pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;  //求交

            IFeatureCursor pFeatureCursor = pFeatureLayer.FeatureClass.Search(pSpatialFilter, false);
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                pSelectedFeatureList.Add(pFeature);
                pFeature = pFeatureCursor.NextFeature();
            }
            return pSelectedFeatureList;
        }

        private void ExampleMain_Load(object sender, EventArgs e)
        {

        }

        private void 属性ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            //查询type为乡村的cities
            ILayer layer = GetLayerByName("cities",axMapControl1);
           IFeatureLayer featureLayer = layer as IFeatureLayer; 
           //获取featureLayer的featureClass 
           IFeatureClass featureClass =  featureLayer.FeatureClass; 
           IFeature feature = null;

           IQueryFilter queryFilter = new QueryFilterClass();

           IFeatureCursor featureCusor; 
           //queryFilter.WhereClause = "name = '" + searchName + "'"; 
           queryFilter.WhereClause = "type = '乡村'"; 
           featureCusor = featureClass.Search(queryFilter, true);

           //search的参数第一个为过滤条件，第二个为是否重复执行。

           feature = featureCusor.NextFeature();
           while (feature != null) 
            {
                axMapControl1.Map.SelectFeature(layer, feature);
                feature = featureCusor.NextFeature();
            }
            axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null); 

            //记数
            int count= featureClass.FeatureCount(queryFilter);
            MessageBox.Show("type为乡村的点有"+count+"个");
        }

        public ILayer GetLayerByName(string layerName, AxMapControl axMap)
        {
            for (int i = 0; i < axMap.LayerCount; i++)
            {
                if (axMap.get_Layer(i).Name.EndsWith(layerName))
                {
                    return axMap.get_Layer(i);
                }
            }
            return null;
        }

        private void 空间查询ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            
             //查询type为乡村的cities
            ILayer layer = GetLayerByName("states",axMapControl1);
           IFeatureLayer featureLayer = layer as IFeatureLayer; 
           //获取featureLayer的featureClass 
           IFeatureClass featureClass =  featureLayer.FeatureClass; 
           IFeature feature = null;

           IQueryFilter queryFilter = new QueryFilterClass();

           //ISelectionSet featureSelection; 

           IFeatureCursor featureCusor; 
            
           //queryFilter.WhereClause = "name = '" + searchName + "'"; 
           queryFilter.WhereClause = "NAME = 'Mexico' or NAME = 'Tlaxcala' "; 
           //featureSelection = featureClass.Select(queryFilter, esriSelectionType.esriSelectionTypeIDSet,esriSelectionOption.esriSelectionOptionEmpty,null);
            //featureCusor = featureClass.Search(queryFilter, true);

           //search的参数第一个为过滤条件，第二个为是否重复执行。

           

            //定义和创建用于空间查询的ISpatialFilter接口的对象
            ISpatialFilter spatialFilter = new SpatialFilterClass();
            //默认设定用于查询的空间几何体为当前地图源图层中所有要素几何体的集合
            spatialFilter.Geometry = GetFeatureLayerGeometryUnion(featureClass,queryFilter);

            //根据对空间选择方法的选择采用相应的空间选择方法
            spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            //进行接口转换，使用IFeatureSelection接口选择要素
            ILayer pLayer = GetLayerByName("cities", axMapControl1);
            IFeatureLayer featureLayer2 = pLayer as IFeatureLayer;
            //获取featureLayer的featureClass 
            IFeatureClass featureClass2 = featureLayer2.FeatureClass;
            IFeatureCursor featureCusor2 = featureClass2.Search((IQueryFilter)spatialFilter, true);

            //search的参数第一个为过滤条件，第二个为是否重复执行。
            axMapControl1.Map.ClearSelection();
            axMapControl1.Refresh();

            IFeature  feature2 = featureCusor2.NextFeature();
            while (feature2 != null)
            {
                axMapControl1.Map.SelectFeature(pLayer, feature2);
                feature2 = featureCusor2.NextFeature();
            }
            axMapControl1.Refresh(esriViewDrawPhase.esriViewGeoSelection, null, null);

            //记数
            int count = featureClass2.FeatureCount((IQueryFilter)spatialFilter);
            MessageBox.Show("符合的点有" + count + "个");
           

        }


        /// <summary>
        /// 将矢量图层中所有要素的几何体进行Union操作得到一个合并后的新几何体。
        /// </summary>
        /// <param name="featureLayer">进行操作的矢量图层</param>
        /// <returns>合并后的新几何体</returns>
        private IGeometry GetFeatureLayerGeometryUnion(IFeatureClass featureClass, IQueryFilter queryFilter)
        {
            //定义IGeometry接口的对象，存储每一步拓扑操作后得到的几何体
            IGeometry geometry = null;
            //使用ITopologicalOperator接口进行几何体的拓扑操作
            ITopologicalOperator topologicalOperator;
            //使用null作为查询过滤器得到图层中所有要素的游标
            IFeatureCursor featureCursor = featureClass.Search(queryFilter, false);
            //获取IFeature接口的游标中的第一个元素
            IFeature feature = featureCursor.NextFeature();
            //当游标不为空时
            while (feature != null)
            {
                //如果几何体不为空
                if (geometry != null)
                {
                    //进行接口转换，使用当前几何体的ITopologicalOperator接口进行拓扑操作
                    topologicalOperator = geometry as ITopologicalOperator;
                    //执行拓扑合并操作，将当前要素的几何体与已有几何体进行Union，返回新的合并后的几何体
                    geometry = topologicalOperator.Union(feature.Shape);
                }
                else
                    geometry = feature.Shape;
                //移动游标到下一个要素
                feature = featureCursor.NextFeature();
            }
            //返回最新合并后的几何体
            return geometry;
        }
      

    }
}